﻿using CustomerScoreManagement.Api.Data;
using CustomerScoreManagement.Api.Models;
using Dapper;
using System.Collections.Concurrent;
//using System.Data.SqlClient;
using System.Linq;
using Microsoft.Data.SqlClient;

namespace CustomerScoreManagement.Api.Services
{
    public class LeaderboardService
    {

         // 使用并发字典存储客户分数，确保线程安全
        private readonly ConcurrentDictionary<long, Customer> _customers = new();
      
        // 更新客户分数的方法
        public decimal UpdateScore(long customerId, decimal scoreChange)
        {
            // 获取或添加客户记录，初始分数为 0
            var customerScore = _customers.GetOrAdd(customerId, new Customer { CustomerID = customerId, Score = 0 });

            // 更新客户分数
            customerScore.Score += scoreChange;

            // 如果分数小于等于 0，则移除该客户
            if (customerScore.Score <= 0)
            {
                _customers.TryRemove(customerId, out _);
            }

            // 返回更新后的分数
            return customerScore.Score;
        }

        // 获取排行榜的方法
        public Customer[] GetLeaderboard(int start, int end)
        {
            // 查询分数大于 0 的客户并按分数降序排序，再按客户 ID 升序排序
            return _customers.Values
                .Where(c => c.Score > 0)
                .OrderByDescending(c => c.Score)
                .ThenBy(c => c.CustomerID)
                .Skip(start - 1) // 跳过前面的客户
                .Take(end - start + 1) // 取出指定范围内的客户
                .Select((c, index) =>
                {
                    c.Rank = start + index; // 计算并设置客户的排名
                    return c;
                }).ToArray(); // 转换为数组返回
        }

        // 获取指定客户及其邻居分数的方法
        public Customer[] GetNeighbors(long customerId, int high, int low)
        {
            // 查询分数大于 0 的客户并排序
            var sortedCustomers = _customers.Values
                .Where(c => c.Score > 0)
                .OrderByDescending(c => c.Score)
                .ThenBy(c => c.CustomerID)
                .ToList();

            // 找到指定客户
            var customer = sortedCustomers.FirstOrDefault(c => c.CustomerID == customerId);
            if (customer == null) return Array.Empty<Customer>(); // 如果未找到客户，返回空数组

            // 获取客户在排序列表中的索引
            var index = sortedCustomers.IndexOf(customer);

            // 获取邻居客户的范围
            var neighbors = sortedCustomers.Skip(Math.Max(0, index - low)) // 从低排名开始
                .Take(low + 1 + high) // 获取邻居数量
                .ToArray();

            // 设置邻居客户的排名并返回
            return neighbors.Select((c, idx) =>
            {
                c.Rank = index - low + idx + 1; // 计算并设置邻居客户的排名
                return c;
            }).ToArray();
        }
    }
}
